package com.atguigu.spzx.manager.interceptor;

import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.model.entity.sys.SysUser;
import com.atguigu.spzx.model.exception.SpzxException;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 拦截器的使用：
 *  1、创建拦截器 编写业务
 *  2、注册拦截器
 */
//@Component
public class LoginAuthInterceptor_ConcurrentHashMap implements HandlerInterceptor {
    //RedisTemplate和StringRedisTemplate存储数据到redis中时 采用的序列化方式不同  不能混用
    //优先使用ThreadLocal
    private static ConcurrentHashMap<Thread, SysUser> SYSUSER_MAP = new ConcurrentHashMap<>();
    @Resource
    StringRedisTemplate stringRedisTemplate;
    //http://192.168.1.1:8501/admin/system/index/logout  该路径不属于放行白名单 一定会校验登录状态
    //每次异步请求都会预先发送预检请求  预检请求不会携带token
    //预检请求直接放行 不能拦截校验
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        System.out.println(request.getRequestURI()+" , "+request.getMethod());
        if("OPTIONS".equals(request.getMethod().toUpperCase())){
            return true;//预检请求放行
        }
        //1、获取请求头中的token
        String token = request.getHeader("token");
        //2、token不存在 或者 token过期(在redis中获取不到用户信息) 拒绝请求，抛出自定义异常:需要登录
        String userInfoJson = null;
        if(!StringUtils.isEmpty(token)){
            //获取redis中的登录状态
            userInfoJson = stringRedisTemplate.opsForValue().get("sys:user:login:" + token);
        }
        //userInfoJson为空 表示未登录
        if(StringUtils.isEmpty(userInfoJson)){
            throw new SpzxException(ResultCodeEnum.LOGIN_STATUS_ERROR);
        }

        SysUser sysUser = JSON.parseObject(userInfoJson, SysUser.class);
        SYSUSER_MAP.put(Thread.currentThread() , sysUser);

        //3、登录状态正常放行请求
        return true;
    }
    public static SysUser getSysUser(){
        return SYSUSER_MAP.get(Thread.currentThread());
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion--完成收尾操作");
        //移除使用过的数据
        SYSUSER_MAP.remove(Thread.currentThread());
    }
}
